package com.example.learningspringboot.email.controller;

import com.example.learningspringboot.email.service.EmailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author: Shu Ting
 * @CreateTime: 2024-08-22 23:41
 * @Description: Java发送邮件测试
 * @Version: 1.0
 */

@RestController
@RequestMapping("/email")
@Slf4j
public class EmailController {

    /**
     * 在Bean的依赖注入上使用的构造函数方式,依赖注入的Bean对象使用final来修饰;
     *下面是这样做的原因:
     * 1.不可变性 (Immutability)
     * 优势:一旦在构造函数中赋值，就不能再被修改,防止在类的其他方法中意外重新赋值,确保依赖关系在整个对象生命周期中保持一致
     * 2.线程安全，具体需要DeepSeek
     * 3.明确的设计意图
     * 4.编译时检查,如果没有初始化final字段，编译器会报错,如果忘记这行赋值，编译错误：variable productRepository might not have been initialized
     * 5.与Spring框架的协作
     * 6.防止NPE（空指针异常），我们可以在构造函数赋值的时候进行null检查
     * 7.函数式编程风格
     * 8.与记录类（Record）的兼容性
     * 总结:
     * 使用final修饰注入的bean是Spring开发中的最佳实践，因为它：
     * ✅ 增强安全性：防止意外修改依赖
     * ✅ 提高可读性：明确表达设计意图
     * ✅ 支持线程安全：天然的不可变对象
     * ✅ 便于测试：依赖关系明确且稳定
     * ✅ 编译时保障：编译器帮助检查初始化
     * ✅ 符合函数式编程原则：鼓励不可变性
     */
    private final EmailService emailService;

    /**
     * 这里我们使用的构造函数进行依赖注入
     */
    @Autowired
    public EmailController(EmailService emailService) {
        this.emailService = emailService;
    }

    @PostMapping("/sendEmail")
    public String sendMail() {
        log.info("sendEmail");
        String from = "870398662@qq.com";
        String to = "1135222061@qq.com";
        String cc = "shuting198912@outlook.com";
        String subject = "发送Email测试";
        String text = "一个人的生活中有多少有益的朋友、成功的朋友，可能就预示着这个人未来会取得多大的成就!!";
        emailService.sendMail(from,to,cc,subject,text);
        return "success";
    }
}
